---------------------------------------------------------------------------------------
-- Driver to demonstrate the use of the HTTP module for DigiLinX
-- Author:  Josh Kewley
-- Company: Insario Corporation
--          Scottsdale, AZ
-- Date: 03/27/2008
---------------------------------------------------------------------------------------

-- load the http module
local HTTP = require "http"

-- Configure these debugging categories as you wish. Some of them provide a great deal of data
setDebug("HttpTEST", "on")
setDebug("Http", "on")
setDebug("HttpDetail", "on")
setDebug("HttpSocket", "on")
setDebug("HttpStream", "off")
setDebug("Url", "off")

RevisionNumber="4.2"

-- The next three lines should me modified to reflect your setup
-- User/Password configuration is not required, but will work if you secure the time.asp page
local theUrl = "http://10.15.15.56/time.asp"
local theUser = "testuser"
local thePass = "p@ssword1"

-- Shorthand wrapper for debugging messages
function DB(someMessg)
  debug("HttpTEST", someMessg)  
end 

-- Say hello to the trace application
DB("Custom driver is loading")

-- wrapper for creating the infrastructure to support a DigiLinX node
function createButton(id,label)
    local aNode = createSubNode(""..id) --concat an empty string with the number to ensure that createSubNode is called with a string
    aNode.state=0
    DB("Creating button: "..label)

  -- This doesn't have anything to do with the HTTP module, but it demonstrates handling button presses
	function aNode:handle_button(cmd)
    DB("Command came in: "..unpack(cmd.params))
    if (cmd.params[1]:upper() == "PRESS") then
        aNode:setStatus("indicatorState", aNode.flipState())
    end
  end

	-- handle an unknown command. Not likely, but useful in case it happens
	function aNode:default_handle_command(cmd)
    DB("Unexpected command came in: "..cmd.command)
  end

  -- add a method to the node that flips the indicator state..
  -- This would be easier if Lua had a tertiary operator
  function aNode:flipState()
      if aNode.state==0 then
          aNode.state=1
      else
          aNode.state=0
      end
      return aNode.state
  end

	-- set the label field in the status report. This changes the text of the button in the interface. 
	-- We'll use it later with the text returned from time.asp
	aNode:setStatus("label", label)

	-- assume an initial "off" state
	aNode:setStatus("indicatorState", "0")
	
	return aNode
end

-- Create persistent hard references to the buttons that we will manipulate.
local First = createButton(1,"First Test")
local Second = createButton(2,"Second Test")

-- version helps me keep track of which copy of the sample you are using
DB("Starting version "..RevisionNumber)

-- Passing an empty body. For Proliphix, this will contain a list of commands to be sent
local theBody = "BODY"
-- Response is a table with body, headers, (status) code, and error
local response = {}
-- How many milliseconds between queries. This example uses 15 seconds
local refreshFrequency = 15* 1000

-- Create a variable that references a timer. Hard reference is required, or the timer will be garbage collected.
-- The timer will run every 'refreshFrequency' and call the anonymous function defined as the second parameter
local hardReference = createTimer(refreshFrequency, function(timer)
                                                        DB("Refreshing Buttons")
                                                        -- manually stop the timer. I've found greater reliability with this approach than with 
                                                        -- returning the refreshFrequency from this method, as suggested in the Digi dev docs.
                                                        timer:cancel()
                                                        --call the POST using the HTTP module defined at the top of this driver
                                                        response.body, response.headers, response.code, response.error = HTTP.Post({url = theUrl,
                                                                                                                                    user = theUser,
                                                                                                                                    pass = thePass,
                                                                                                                                    body = theBody})
                                                        if (response.body) then
                                                          -- Update the label of the first button only
                                                          First:setStatus("label", response.body) 
                                                          DB("Set Button to "..response.body)                                                      
                                                        end
                                                        -- restart the timer
                                                        timer:queue(refreshFrequency)
                                                        return refreshFrequency
                                                    end)
-- This message will appear right away, but the timer will continue to run
DB("Driver loaded")